package org.framework.lazy.cloud.network.heartbeat.common.utils;

import io.netty.channel.Channel;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import io.netty.util.AttributeKey;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;

/**
 * 通道属性绑定工具
 */
public class ChannelAttributeKeyUtils {

    private static final AttributeKey<String> VISITOR_ID = AttributeKey.newInstance("visitorId");
    private static final AttributeKey<Integer> VISITOR_PORT = AttributeKey.newInstance("visitorPort");
    private static final AttributeKey<String> CLIENT_ID = AttributeKey.newInstance("clientId");
    private static final AttributeKey<String> APP_KEY = AttributeKey.newInstance("appKey");
    private static final AttributeKey<String> APP_SECRET = AttributeKey.newInstance("appSecret");
    private static final AttributeKey<String> ORIGINAL_IP = AttributeKey.newInstance("originalIp");
    private static final AttributeKey<Integer> OUT_FLOW = AttributeKey.newInstance("outFlow");
    private static final AttributeKey<Integer> IN_FLOW = AttributeKey.newInstance("inFlow");

    private static final AttributeKey<Channel> NEXT_CHANNEL = AttributeKey.newInstance("nextChannel");
    private static final AttributeKey<Channel> TRANSFER_NEXT_CHANNEL = AttributeKey.newInstance("transferNextChannel");
    private static final AttributeKey<NettyByteBuf> NETTY_BYTE_BUF_DATA = AttributeKey.newInstance("nettyByteBufData");
    private static final AttributeKey<Byte> NETTY_SOCKS5_ADDRESS_TYPE = AttributeKey.newInstance("socks5AddressType");


    /**
     * 为通道绑定 访客属性
     *
     * @param channel   通道
     * @param visitorId 访客ID
     */
    public static void buildVisitorId(Channel channel, byte[] visitorId) {
        channel.attr(VISITOR_ID).set(new String(visitorId));
    }

    /**
     * 为通道绑定 访客属性
     *
     * @param channel   通道
     * @param visitorId 访客ID
     */
    public static void buildVisitorId(Channel channel, String visitorId) {
        channel.attr(VISITOR_ID).set(visitorId);
    }

    /**
     * 获取 通道中访客ID
     *
     * @param channel 通道
     */
    public static String getVisitorId(Channel channel) {
        return channel.attr(VISITOR_ID).get();
    }


    /**
     * 为通道绑定 访客属性
     *
     * @param channel  通道
     * @param clientId 客户端ID
     */
    public static void buildClientId(Channel channel, byte[] clientId) {
        channel.attr(CLIENT_ID).set(new String(clientId));
    }

    /**
     * 为通道绑定 访客属性
     *
     * @param channel  通道
     * @param clientId 客户端ID
     */
    public static void buildClientId(Channel channel, String clientId) {
        channel.attr(CLIENT_ID).set(clientId);
    }

    /**
     * 获取 通道中访客ID
     *
     * @param channel 通道
     */
    public static String getClientId(Channel channel) {
        return channel.attr(CLIENT_ID).get();
    }


    /**
     * 为通道绑定 出口流量
     *
     * @param channel 通道
     * @param outFlow 出口流量
     */
    public static void buildOutFlow(Channel channel, Integer outFlow) {
        channel.attr(OUT_FLOW).set(outFlow);
    }

    /**
     * 获取 通道中出口流量
     *
     * @param channel 通道
     */
    public static Integer getOutFlow(Channel channel) {
        return channel.attr(OUT_FLOW).get();
    }

    /**
     * 为通道绑定 进口流量
     *
     * @param channel 通道
     * @param inFlow  进口流量
     */
    public static void buildInFlow(Channel channel, Integer inFlow) {
        channel.attr(IN_FLOW).set(inFlow);
    }

    /**
     * 获取 通道中进口流量
     *
     * @param channel 通道
     */
    public static Integer getInFlow(Channel channel) {
        return channel.attr(IN_FLOW).get();
    }

    /**
     * 为通道绑定 通道中访客端口
     *
     * @param channel     通道
     * @param visitorPort 进口流量
     */
    public static void buildVisitorPort(Channel channel, Integer visitorPort) {
        channel.attr(VISITOR_PORT).set(visitorPort);
    }

    /**
     * 获取 通道中访客端口
     *
     * @param channel 通道
     */
    public static Integer getVisitorPort(Channel channel) {
        return channel.attr(VISITOR_PORT).get();
    }


    /**
     * 为通道绑定  下一个通道
     *
     * @param channel     通道
     * @param nextChannel 下一个通道
     */
    public static void buildNextChannel(Channel channel, Channel nextChannel) {
        channel.attr(NEXT_CHANNEL).set(nextChannel);
    }


    /**
     * 获取 通道中下一个通道
     *
     * @param channel 通道
     */
    public static Channel getNextChannel(Channel channel) {
        return channel.attr(NEXT_CHANNEL).get();
    }
    /**
     * 为通道绑定  下一个通道
     *
     * @param channel     通道
     * @param nextChannel 下一个通道
     */
    public static void buildTransferNextChannel(Channel channel, Channel nextChannel) {
        channel.attr(TRANSFER_NEXT_CHANNEL).set(nextChannel);
    }


    /**
     * 获取 通道中下一个通道
     *
     * @param channel 通道
     */
    public static Channel getTransferNextChannel(Channel channel) {
        return channel.attr(TRANSFER_NEXT_CHANNEL).get();
    }
    /**
     * 为通道绑定  传输数据
     *
     * @param channel      通道
     * @param nettyByteBuf 传输数据
     */
    public static void buildNettyByteBufData(Channel channel, NettyByteBuf nettyByteBuf) {
        channel.attr(NETTY_BYTE_BUF_DATA).set(nettyByteBuf);
    }


    /**
     * 获取 通道中传输数据
     *
     * @param channel 通道
     */
    public static NettyByteBuf getNettyByteBufData(Channel channel) {
        return channel.attr(NETTY_BYTE_BUF_DATA).get();
    }


    /**
     * 为通道绑定 通道中访客端口
     *
     * @param channel 通道
     * @param appKey  应用key
     */
    public static void buildAppKey(Channel channel, String appKey) {
        channel.attr(APP_KEY).set(appKey);
    }

    /**
     * 获取 通道中 应用key
     *
     * @param channel 通道
     */
    public static String getAppKey(Channel channel) {
        return channel.attr(APP_KEY).get();
    }

    /**
     * 为通道绑定 应用密钥
     *
     * @param channel   通道
     * @param appSecret 应用密钥
     */
    public static void buildAppSecret(Channel channel, String appSecret) {
        channel.attr(APP_SECRET).set(appSecret);
    }

    /**
     * 获取 通道中 应用密钥
     *
     * @param channel 通道
     */
    public static String getAppSecret(Channel channel) {
        return channel.attr(APP_SECRET).get();
    }

    /**
     * 为通道绑定 原始IP
     *
     * @param channel    通道
     * @param originalIp 原始IP
     */
    public static void buildOriginalIp(Channel channel, String originalIp) {
        channel.attr(ORIGINAL_IP).set(originalIp);
    }

    /**
     * 获取 通道中 原始IP
     *
     * @param channel 通道
     */
    public static String getOriginalIp(Channel channel) {
        return channel.attr(ORIGINAL_IP).get();
    }

    /**
     * 为通道绑定 请求地址类型
     *
     * @param channel    通道
     * @param socks5AddressTypeByte 地址类型
     * @see Socks5AddressType#valueOf(byte)
     */
    public static void buildSocks5AddressType(Channel channel, Byte socks5AddressTypeByte) {
        channel.attr(NETTY_SOCKS5_ADDRESS_TYPE).set(socks5AddressTypeByte);
    }

    /**
     * 获取 通道中 请求地址类型
     *
     * @param channel 通道
     */
    public static Byte getSocks5AddressType(Channel channel) {
        return channel.attr(NETTY_SOCKS5_ADDRESS_TYPE).get();
    }
}
